package models

import (
	"time"
)

// Category 分类模型，对应数据库中的categories表
type Category struct {
	ID        uint      `gorm:"primaryKey;autoIncrement;type:bigint unsigned" json:"id"` // 主键，自增
	Name      string    `gorm:"type:varchar(100);not null" json:"name"`                  // 分类名称
	ParentID  *uint     `gorm:"default:null;type:bigint unsigned" json:"parent_id"`      // 父分类ID，null表示顶级分类
	Level     int       `gorm:"default:1" json:"level"`                                  // 分类层级，1为顶级
	Path      string    `gorm:"type:varchar(500)" json:"path"`                           // 分类路径，如：Go/基础
	UserID    uint      `gorm:"not null;index;type:bigint unsigned" json:"user_id"`      // 用户ID
	CreatedAt time.Time `json:"created_at"`                                              // 创建时间
	UpdatedAt time.Time `json:"updated_at"`                                              // 更新时间

	// 关联关系
	Parent   *Category   `gorm:"foreignKey:ParentID" json:"parent,omitempty"`   // 父分类
	Children []*Category `gorm:"foreignKey:ParentID" json:"children,omitempty"` // 子分类
	User     User        `gorm:"foreignKey:UserID" json:"user,omitempty"`       // 所属用户
}

// TableName 指定表名
func (Category) TableName() string {
	return "categories"
}

// CategoryCreateRequest 创建分类请求结构体
type CategoryCreateRequest struct {
	Name     string `json:"name" binding:"required,min=1,max=100"` // 分类名称，必填，1-100字符
	ParentID *uint  `json:"parent_id"`                             // 父分类ID，可选
}

// CategoryUpdateRequest 更新分类请求结构体
type CategoryUpdateRequest struct {
	Name     string `json:"name" binding:"required,min=1,max=100"` // 分类名称，必填，1-100字符
	ParentID *uint  `json:"parent_id"`                             // 父分类ID，可选
}

// CategoryQueryRequest 分类查询请求结构体
type CategoryQueryRequest struct {
	Page     int    `form:"page" binding:"min=1"`      // 页码，最小为1
	PageSize int    `form:"page_size" binding:"min=1"` // 每页数量，最小为1
	Search   string `form:"search"`                    // 搜索关键词
	ParentID *uint  `form:"parent_id"`                 // 父分类ID，用于查询子分类
}

// CategoryResponse 分类响应结构体
type CategoryResponse struct {
	ID        uint                `json:"id"`
	Name      string              `json:"name"`
	ParentID  *uint               `json:"parent_id"`
	Level     int                 `json:"level"`
	Path      string              `json:"path"`
	UserID    uint                `json:"user_id"`
	CreatedAt time.Time           `json:"created_at"`
	UpdatedAt time.Time           `json:"updated_at"`
	Parent    *CategoryResponse   `json:"parent,omitempty"`
	Children  []*CategoryResponse `json:"children,omitempty"`
}

// CategoryTreeResponse 分类树响应结构体
type CategoryTreeResponse struct {
	ID       uint                    `json:"id"`
	Name     string                  `json:"name"`
	Level    int                     `json:"level"`
	Path     string                  `json:"path"`
	Children []*CategoryTreeResponse `json:"children,omitempty"`
}

// CategoryListResponse 分类列表响应结构体
type CategoryListResponse struct {
	Categories []*CategoryResponse `json:"categories"`
	Total      int64               `json:"total"`
	Page       int                 `json:"page"`
	PageSize   int                 `json:"page_size"`
	TotalPages int                 `json:"total_pages"`
}

// ToResponse 将Category转换为CategoryResponse
func (c *Category) ToResponse() *CategoryResponse {
	resp := &CategoryResponse{
		ID:        c.ID,
		Name:      c.Name,
		ParentID:  c.ParentID,
		Level:     c.Level,
		Path:      c.Path,
		UserID:    c.UserID,
		CreatedAt: c.CreatedAt,
		UpdatedAt: c.UpdatedAt,
	}

	// 转换父分类
	if c.Parent != nil {
		resp.Parent = c.Parent.ToResponse()
	}

	// 转换子分类
	if len(c.Children) > 0 {
		resp.Children = make([]*CategoryResponse, len(c.Children))
		for i, child := range c.Children {
			resp.Children[i] = child.ToResponse()
		}
	}

	return resp
}

// ToTreeResponse 将Category转换为CategoryTreeResponse
func (c *Category) ToTreeResponse() *CategoryTreeResponse {
	resp := &CategoryTreeResponse{
		ID:    c.ID,
		Name:  c.Name,
		Level: c.Level,
		Path:  c.Path,
	}

	// 转换子分类
	if len(c.Children) > 0 {
		resp.Children = make([]*CategoryTreeResponse, len(c.Children))
		for i, child := range c.Children {
			resp.Children[i] = child.ToTreeResponse()
		}
	}

	return resp
}
